<html>
<head><meta charset="utf-8"><title>Fixing &quot;original sin&quot; of const qual in external crates · t-compiler/const-eval · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/index.html">t-compiler/const-eval</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html">Fixing &quot;original sin&quot; of const qual in external crates</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="202471002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202471002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Brian Campbell <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202471002">(Jun 30 2020 at 17:45)</a>:</h4>
<p>Was reading the stabilization discussion in <a href="https://github.com/rust-lang/rust/issues/49146">https://github.com/rust-lang/rust/issues/49146</a>, and came across this:</p>
<blockquote>
<p>In my view, the "original sin" here was not falling back to type-based qualification for const and statics defined in external crates. However, I believe that this has been the case since 1.0, and I suspect that quite a lot of code depends on it. As soon as you allow const initializers for which static analysis cannot be perfectly precise, it becomes possible to modify those initializers in such a way that they will produce the same value without static analysis being able to prove it.</p>
</blockquote>
<p>Would it be possible to fix this in a lint, which could maybe become <code>#[deny]</code> by default in a future version/edition, which would forbid public consts which are value qualified, as a way to avoid accidentally breaking backwards compatibility with downstream crates? Or are there too many actual use cases for this?</p>
<p>Also, on the general topic, is there any semver policy for changing the value of a publicly exported const? Obviously, it's possible for that to break downstream crates, but we allow that for things like type inference ambiguities or adding new names to a module even if that could break a glob import, with the general policy that these kind of breakages can be cleaned up just by resolving an ambiguity.</p>
<p>Is there some subset of value changes that could be reasonably allowed by semver policy? After thinking about it a bit, with full Turing-complete const eval, probably not, since you can't tell how someone would depend on the value of an exported const; so it's probably the case that any change to the value would have to be semver incompatible.</p>



<a name="202478432"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202478432" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202478432">(Jun 30 2020 at 18:46)</a>:</h4>
<blockquote>
<p>Would it be possible to fix this in a lint, which could maybe become #[deny] by default in a future version/edition, which would forbid public consts which are value qualified, as a way to avoid accidentally breaking backwards compatibility with downstream crates? Or are there too many actual use cases for this?</p>
</blockquote>
<p>There would have to be some sort of alternative for people whose code violates the new semantics, and I don't see a feasible one. I suppose I don't have proof that real code would break, only suspicions. A crater run would help to clarify this. I think it will be hard to put this particular genie back in the bottle.</p>
<blockquote>
<p>Also, on the general topic, is there any semver policy for changing the value of a publicly exported const? Obviously, it's possible for that to break downstream crates, but we allow that for things like type inference ambiguities or adding new names to a module even if that could break a glob import, with the general policy that these kind of breakages can be cleaned up just by resolving an ambiguity.</p>
</blockquote>
<p>The canonical example is <code>arr[other_crate::SOME_CONST]</code>, but there will always be some way for downstream crates to depend on the exact value of a <code>const</code> so long as it is observable. It's up to library authors to document the guarantees they provide.</p>



<a name="202482688"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202482688" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Brian Campbell <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202482688">(Jun 30 2020 at 19:22)</a>:</h4>
<blockquote>
<p>There would have to be some sort of alternative for people whose code violates the new semantics, and I don't see a feasible one. I suppose I don't have proof that real code would break, only suspicions. A crater run would help to clarify this. I think it will be hard to put this particular genie back in the bottle.</p>
</blockquote>
<p>That's why it would have to be a lint, not mandatory. I think introducing a lint at <code>#[allow]</code>, switching it to <code>#[warn]</code> in a later release, and then in an edition to <code>#[deny]</code> would give the opt-out of switching back to <code>#[allow]</code> if you still need that behavior after the edition switch.</p>
<blockquote>
<p>The canonical example is <code>arr[other_crate::SOME_CONST]</code>, but there will always be some way for downstream crates to depend on the exact value of a const so long as it is observable. It's up to library authors to document the guarantees they provide.</p>
</blockquote>
<p>With const generics, could you have that fail typechecking unless <code>arr</code> is <code>[_; other_crate::SOME_CONST + delta]</code>?</p>
<p>But yeah, that kind of typechecking would probably hit the halting problem pretty quickly, so you can't in general.</p>



<a name="202483922"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202483922" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202483922">(Jun 30 2020 at 19:33)</a>:</h4>
<p><span class="user-mention" data-user-id="121053">@varkor</span> ^</p>



<a name="202527344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527344">(Jul 01 2020 at 03:24)</a>:</h4>
<p><span class="user-mention" data-user-id="118594">@ecstatic-morse</span> why is any of this considered a problem? my reasoning ages ago was that <code>const</code> initializers were part of semver</p>



<a name="202527368"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527368" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527368">(Jul 01 2020 at 03:25)</a>:</h4>
<p>and one idea for avoiding a complex system with <code>const Trait</code> and <code>?const Trait</code> bounds etc. was to just have an attribute or something that opts into that "body is exposed publicly" behavior, with analyses being able to infer complex-to-express requirements from said body</p>



<a name="202527523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527523">(Jul 01 2020 at 03:28)</a>:</h4>
<p>oh I see what the intent is</p>



<a name="202527536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527536">(Jul 01 2020 at 03:28)</a>:</h4>
<p>presumably we could try to be even more precise and just evaluate the const but that can't always work for associated consts hmpf</p>



<a name="202527613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527613">(Jul 01 2020 at 03:30)</a>:</h4>
<p>I wonder in which cases you really want to refactor <code>const</code> initializers, like an example in the wild</p>



<a name="202527619"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527619" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527619">(Jul 01 2020 at 03:30)</a>:</h4>
<p>(also, I'm not sure using <code>drop(...)</code> in the examples works. since it doesn't compile to a MIR <code>Drop</code>)</p>



<a name="202527625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202527625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202527625">(Jul 01 2020 at 03:30)</a>:</h4>
<p>ftr the comment in question is <a href="https://github.com/rust-lang/rust/issues/49146#issuecomment-617995319">https://github.com/rust-lang/rust/issues/49146#issuecomment-617995319</a></p>



<a name="202528137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202528137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202528137">(Jul 01 2020 at 03:43)</a>:</h4>
<p>Presently, refactoring a const initializer into a <code>const fn</code> turns off the (local) value-based static analysis. I can imagine people wanting to do this as we add more features. As I mentioned above though,  I don't know how common it is for people to depend on the value-based analysis for the final value of a const.</p>



<a name="202528148"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Fixing%20%22original%20sin%22%20of%20const%20qual%20in%20external%20crates/near/202528148" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Fixing.20.22original.20sin.22.20of.20const.20qual.20in.20external.20crates.html#202528148">(Jul 01 2020 at 03:43)</a>:</h4>
<p>I suspect not very.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>